package com.guldan.jaina.task;

import com.alibaba.fastjson.JSON;
import com.guldan.core.constants.CommonConstant;
import com.guldan.core.enums.ValidatingRegisterTypeEn;
import com.guldan.core.redis.CacheService;
import com.guldan.core.redis.DistributeLock;
import com.guldan.jaina.dto.citizeninfo.CitizenInfoDTO;
import com.guldan.jaina.dto.progress.BarDTO;
import com.guldan.jaina.dto.users.UsersDTO;
import com.guldan.jaina.manager.CitizenInfoManager;
import com.guldan.jaina.utils.UserUtils;
import org.apache.taglibs.standard.tag.common.xml.WhenTag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created by Silas.
 * Date: 2016/12/31
 * Time: 18:03
 */
public class CitizenUploadThread implements Runnable {

    public Logger logger = LoggerFactory.getLogger(getClass());


    private CitizenInfoManager citizenInfoManager;

    private LinkedBlockingQueue<CitizenInfoDTO> queue;

    private BarDTO barDTO;

    private String batchId;

    private String threadName;

    private UsersDTO usersDTO;

    private CacheService cacheService;

    public void setCacheService(CacheService cacheService) {
        this.cacheService = cacheService;
    }

    public void setUsersDTO(UsersDTO usersDTO) {
        this.usersDTO = usersDTO;
    }

    public void setThreadName(String threadName) {
        this.threadName = threadName;
    }

    public void setCitizenInfoManager(CitizenInfoManager citizenInfoManager) {
        this.citizenInfoManager = citizenInfoManager;
    }

    public void setQueue(LinkedBlockingQueue<CitizenInfoDTO> queue) {
        this.queue = queue;
    }

    public void setBarDTO(BarDTO barDTO) {
        this.barDTO = barDTO;
    }

    public void setBatchId(String batchId) {
        this.batchId = batchId;
    }


    @Override
    public void run() {

        UserUtils.setUser(this.usersDTO);

        logger.info(this.threadName + " begin");

        DistributeLock lock1 = new DistributeLock(), lock2 = new DistributeLock();

        long cost = 0;
        int count = 0;
        while (queue != null && queue.size() > 0) {
            CitizenInfoDTO dto = null;
            count++;
            try {
                dto = queue.take();

                /* lock begin */
                long a = System.currentTimeMillis();
                lock1 = new DistributeLock(String.format(CommonConstant.LOCK_KEY_UPLOAD_CITIZEN_IdentNumber, dto.getIdentNumber()), cacheService);
                lock2 = new DistributeLock(String.format(CommonConstant.LOCK_KEY_UPLOAD_CITIZEN_HouseholdRegisterNumber, dto.getHouseholdRegisterNumber()), cacheService);

                lock1.lock1();
                lock2.lock1();
                /*while (!lock1.lock()) {
                    Thread.sleep(500L);
                }
                lock2 = new DistributeLock(String.format(CommonConstant.LOCK_KEY_UPLOAD_CITIZEN_HouseholdRegisterNumber, dto.getHouseholdRegisterNumber()), cacheService);
                while (!lock2.lock()) {
                    Thread.sleep(500L);
                }*/
                cost += System.currentTimeMillis() - a;
                /* lock end */

                Map<String, Object> map = citizenInfoManager.validateAndUpdate(dto, batchId);
                Integer validatingResult = (Integer) map.get("code");

                if (validatingResult.intValue() == ValidatingRegisterTypeEn.success.getCode().intValue()) {
                    barDTO.finishAdd(true);
                } else {
                    barDTO.finishAdd(false);
                }
            } catch (Exception ex) {
                ex.printStackTrace();

                logger.error("QQQQQQQQQ+" + ex.getMessage() + "\n" + JSON.toJSONString(dto));
                barDTO.finishAdd(false);
            } finally {
                logger.info("barDTO SSSSS " + barDTO.toString());
                long a = System.currentTimeMillis();

                lock2.unLock1();
                lock1.unLock1();
                cost += System.currentTimeMillis() - a;
            }
        }
        logger.info(threadName + "end count=" + count + " cost=" + cost);
    }


}
